//
//  HMPullDownRefreshView.swift
//  HMWeibo12
//
//  Created by iOS on 16/9/23.
//  Copyright © 2016年 iOS. All rights reserved.
//

import UIKit

/// 刷新控件的高度
let HMPullDownRefreshViewHeight: CGFloat = 60

/// 状态枚举
enum HMPullDownRefreshViewStatus {
    case normal     // 下拉刷新
    case pulling    // 释放刷新
    case refreshing // 正在刷新
}

class HMPullDownRefreshView: UIView {
    
    /// 进入刷新的回调
    var refreshingCallback: (() -> Void)?
    
    // 记录父控件
    var superScrollView: UIScrollView?
    
    // 当前状态, 默认为下拉刷新状态
    private var currentStatus: HMPullDownRefreshViewStatus = .normal {
        didSet {
            // 判断最新状态
            switch currentStatus {
            case .normal:
                print("normal")
                // 设置文字为 下拉刷新
                messageLabel.text = "下拉刷新"
                
                // 箭头转回来
                UIView.animate(withDuration: 0.25, animations: { 
                    self.arrowImageView.transform = CGAffineTransform.identity
                })
                
            case .pulling:
                print("pulling")
                // 设置文字为 释放刷新
                messageLabel.text = "释放刷新"
                
                // 箭头转上去
                UIView.animate(withDuration: 0.25, animations: {
                    self.arrowImageView.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI - 0.001))
                })
                
            case .refreshing:
                print("refreshing")
                // 设置文字为 正在刷新
                messageLabel.text = "正在刷新..."
                
                // 隐藏箭头
                arrowImageView.isHidden = true
                // 显示风火轮
                fhlImageView.isHidden = false
                
                // 风火轮转起来
                let rotationAnim = CABasicAnimation(keyPath: "transform.rotation")
                rotationAnim.toValue = M_PI * 2
                rotationAnim.duration = 2
                rotationAnim.repeatCount = MAXFLOAT
                rotationAnim.isRemovedOnCompletion = false
                
                // 添加动画
                // forKey,取一个名称后,下次添加动画如果发现有名字一样的动画,会先停掉前一个动画,1️⃣后面添加进的动画为主
                fhlImageView.layer.add(rotationAnim, forKey: "rotation")
                
                // TODO: 要停在导航栏下面
                UIView.animate(withDuration: 0.25, animations: {
                    self.superScrollView?.contentInset.top += HMPullDownRefreshViewHeight
                })
                
                // 告诉别人刷新控件进入刷新了
                refreshingCallback?()
            }
        }
    }
    
    // MARK: - 公开的方法
    /// 主动进入刷新状态
    func beginRefreshing() -> Void {
        currentStatus = .refreshing
    }
    
    /// 结束刷新
    func endRefreshing() -> Void {
        if currentStatus == .refreshing {
            
            // 顶部间距
            UIView.animate(withDuration: 0.25, animations: { 
                self.superScrollView?.contentInset.top -= HMPullDownRefreshViewHeight
                }, completion: { (_) in
                    // 隐藏风火轮
                    self.fhlImageView.isHidden = true
                    // 显示箭头
                    self.arrowImageView.isHidden = false
                    self.currentStatus = .normal
            })
        }
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override init(frame: CGRect) {
        // 自己内部来确定frame
        let newFrame = CGRect(x: 0, y: -HMPullDownRefreshViewHeight, width: UIScreen.width, height: HMPullDownRefreshViewHeight)
        super.init(frame: newFrame)
        
        setupUI()
    }
    
    private func setupUI() {
        // 设置背景颜色
//        self.backgroundColor = UIColor.brown
        
        // 添加子控件
        addSubview(arrowImageView)
        addSubview(fhlImageView)
        addSubview(messageLabel)
        
        fhlImageView.isHidden = true
        
        // 添加约束
        arrowImageView.translatesAutoresizingMaskIntoConstraints = false
        fhlImageView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        
        // 箭头
        // centerX
        self.addConstraint(NSLayoutConstraint(item: arrowImageView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -30))
        self.addConstraint(NSLayoutConstraint(item: arrowImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        
        // 风火轮
        // centerX
        self.addConstraint(NSLayoutConstraint(item: fhlImageView, attribute: .centerX, relatedBy: .equal, toItem: arrowImageView, attribute: .centerX, multiplier: 1, constant: 0))
        // centerY
        self.addConstraint(NSLayoutConstraint(item: fhlImageView, attribute: .centerY, relatedBy: .equal, toItem: arrowImageView, attribute: .centerY, multiplier: 1, constant: 0))
        
        // messageLabel
        // leading
        self.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
        // centerY
        self.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
    }
    
    deinit {
        // 移除KVO的监听
        superScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    // 刷新控件自己来监听tableView的滚动?
    // 当控件被添加到父控件中后会调用
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        
        superScrollView = newSuperview as? UIScrollView
        
        // 使用KVO监听父控件的 contentOffset 的改变
        // 要监听谁的属性,就用谁来调用
        // observer: NSObject 谁来监听
        // forKeyPath: 要监听的属性
        // NSKeyValueObservingOptions: 选项, 新值,旧值
        // 当对象属性的值改变后会调用监听者的 observeValueforKeyPath:object:change:context:
        superScrollView?.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
//        print("contentOffset 发生了改变 = \(superScrollView?.contentOffset.y)")
        
        let offsetY = superScrollView?.contentOffset.y ?? 0
        // 根据拖动的值来切换状态
        if superScrollView!.isDragging {
            // 拖动 normal <-> pulling
            if offsetY > -124 && currentStatus == .pulling { // -80 > -124
//                print("切换到normal")
                currentStatus = .normal
            } else if offsetY <= -124 && currentStatus == .normal { // -160 < -124
//                print("切换到释放刷新")
                currentStatus = .pulling
            }
        } else {
            // 松手 pulling -> refreshing
            if currentStatus == .pulling {
//                print("切换到正在刷新")
                currentStatus = .refreshing
            }
        }
    }
    
    // MARK: - 懒加载
    /// 箭头
    private lazy var arrowImageView: UIImageView = UIImageView(named: "tableview_pull_refresh")
    
    /// 风火轮
    private lazy var fhlImageView: UIImageView = UIImageView(named: "tableview_loading")
    
    private lazy var messageLabel: UILabel = {
        let label = UILabel()
        
        // 设置
        label.font = UIFont.systemFont(ofSize: 14)
        label.textColor = UIColor.darkGray
        label.text = "下拉刷新"
        
        return label
    }()
}
